package org.uninova.mobis.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.uninova.mobis.api.interfaces.open.routers.RoutinoInterface;
import org.uninova.mobis.pojos.Coordinate;
import org.uninova.mobis.utils.GISUtilsImpl;

/**
 * Servlet implementation class GetDirectionsRoutinoServlet
 * @author PAF
 */
@WebServlet("/GetDirectionsRoutinoServlet")
public class GetDirectionsRoutinoServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GetDirectionsRoutinoServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response) ;
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response) ;
	}
	
	/**
	 * This servlet calculates the routes for personal motorized transports such as cars, motorbikes or transports of goods, using the Routino Router.
	 * It also checks the country according to the coordinates.
	 * 
	 * @param origin		The WSG84 coordinate of the origin location for calculating Routino route
	 * @param destination	The WSG84 coordinate of the destination location for calculating Routino route
	 * @param waypoints		The WSG84 coordinates for waypoints between origin and destination, separated by double exclamation marks(!!)
	 * @param shortest		Boolean value stating if the user wants the shortest (true) or fastest (false) route
	 * @param transportType	The type of transport to use when calculating the route. May be one of foot, bicycle, car, motorbike or transport of goods
	 * @param time			The ISO8601 formatted time and date for the beginning of the trip
	 * 
	 * @return				An array of WSG84 coordinates that point out the route geometry, separated by a comma (,)
	 */
	protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
		String origin = request.getParameter("origin") ;
		String destination = request.getParameter("destination") ;
		String waypoints = request.getParameter("waypoints") ;
		boolean shortest = Boolean.parseBoolean(request.getParameter("shortest")) ;
		String transportType = request.getParameter("transportType") ;
		String time = request.getParameter("time") ;
		boolean isAndroid = Boolean.parseBoolean(request.getParameter("isAndroid")) ;
		//String ccToken = request.getParameter("ccToken") ;
		
		RoutinoInterface ri = new RoutinoInterface() ;
		
		ArrayList<Double> lats = new ArrayList<Double>() ;
		ArrayList<Double> lngs = new ArrayList<Double>() ;
		
		GISUtilsImpl gisUtils = new GISUtilsImpl() ;
		Double originLat, originLng, destLat, destLng ;
		
		boolean oneway = true ;
		boolean turns = true ;
		
		Coordinate coord = gisUtils.getCoordinateFromString(origin) ;
		originLat = coord.lat ;
		originLng = coord.lng ;
		
		coord = gisUtils.getCoordinateFromString(destination) ;
		destLat = coord.lat ;
		destLng = coord.lng ;
		
		String prefix = "" ;
		
		// CHECK WHETHER THE COORDINATES ARE LOCATED IN SWEDEN, GREECE OR SLOVENIA
		
		if (gisUtils.locatedInSweden(originLat, originLng) && gisUtils.locatedInSweden(destLat, destLng)) {
			prefix = "sv" ;
		}
		else if (gisUtils.locatedInSlovenia(originLat, originLng) && gisUtils.locatedInSlovenia(destLat, destLng)) {
			prefix = "sl" ;
		}
		else if (gisUtils.locatedInGreece(originLat, originLng) && gisUtils.locatedInGreece(destLat, destLng)) {
			prefix = "gr" ;
		}
		
		// IF THE COORDINATES ARE LOCATED IN SWEDEN AND THE MEANS OF TRANSPORTATION IS PUBLIC TRANSPORTS, THEN REDIRECT THIS SERVLET
		// TO THE 'GetResRobotRoutes' SERVLET
		
		if (prefix.equals("sv") && transportType.equals("psv")) {
			try {
				if (!isAndroid) {
					if (waypoints == null || waypoints.equals("") || waypoints.equals("null")) {
						
						response.sendRedirect("/MobisRoutePlannerV0.3/GetResRobotRoutes?origin=" + origin + "&destination=" + destination + "&time=" + time + "&waypoints=null") ;
					}
					else {
						response.sendRedirect("/MobisRoutePlannerV0.3/GetResRobotRoutes?origin=" + origin + "&destination=" + destination + "&time=" + time + "&waypoints=" + waypoints) ;
					}
				}
				else {	
					if (time.contains(" "))
						time = time.replace(" ", "%20") ;
					if (waypoints == null || waypoints.equals("") || waypoints.equals("null")) {
						
						response.sendRedirect("/MobisRoutePlannerV0.3/GetResRobotRoutesJSON?origin=" + origin + "&destination=" + destination + "&time=" + time + "&waypoints=null") ;
					}
					else {
						response.sendRedirect("/MobisRoutePlannerV0.3/GetResRobotRoutesJSON?origin=" + origin + "&destination=" + destination + "&time=" + time + "&waypoints=" + waypoints) ;
					}
				}
				return ;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		// ELSE IF THE TRANSPORT TYPE IS CAR (OR MOTORBIKE)
		else {
			lats.add(originLat) ;
			lngs.add(originLng) ;
			
			if (waypoints != null && !waypoints.equals("") && !waypoints.equals("null")) {
				String[] points = null ;
				if (waypoints.contains("!!"))
					points = waypoints.split("!!") ;
				else {
					points = new String[1] ;
					points[0] = waypoints ;
				}
				
				if (points.length > 0) {
					String point ;
					
					for (int i = 0; i < points.length; i++) {
						point = points[i] ;
						coord = gisUtils.getCoordinateFromString(point) ;
						
						lats.add(coord.lat) ;
						lngs.add(coord.lng) ;
					}
				}
			}
			
			lats.add(destLat) ;
			lngs.add(destLng) ;
			
			String result = ri.initRoutinoRouter("/home/paf/routino_data", prefix, "", "", false, false, false, "", "", transportType, shortest, lats, lngs, null, null, null, oneway, turns, 0.0, 0.0, 0.0, 0.0) ;
			System.out.println(result) ;
			String jsonResponse ="{\"route_geometry\":[" ;
			jsonResponse = ri.generateJSONCoordinatesResponse(result, jsonResponse, ",") ;
			jsonResponse += "]}" ;
			
			response.setContentType("text/html;charset=UTF-8");
			
			PrintWriter out;
			try {
				out = response.getWriter();
				out.println(jsonResponse) ;
			    out.close() ;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}
	}
}
